package main

import (
	"context"
	"fmt"
	"sync"
	"time"
)

func processItem(item int, wg *sync.WaitGroup, sem chan struct{}, ctx context.Context) {
	defer wg.Done()
	defer func() { <-sem }() // 释放信号量

	select {
	case <-ctx.Done():
		return // 如果上下文被取消，提前返回
	default:
		// 模拟处理时间
		time.Sleep(100 * time.Millisecond)
		fmt.Printf("Processed item: %d\n", item)
	}
}

func main() {
	// 数据数组
	data := make([]int, 100)
	for i := range data {
		data[i] = i
	}

	// 最大并发协程数
	maxConcurrency := 10

	// 创建一个固定大小的通道作为信号量
	sem := make(chan struct{}, maxConcurrency)

	// 创建一个 WaitGroup 来等待所有协程完成
	var wg sync.WaitGroup

	// 创建一个上下文，用于取消所有协程
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// 启动协程处理数据
	for _, item := range data {
		sem <- struct{}{} // 获取信号量
		wg.Add(1)
		go processItem(item, &wg, sem, ctx)
	}

	// 等待所有协程完成
	wg.Wait()
}
